<template>
    <div class="card">
        <Breadcrumb :home="breadcrumbHome" :model="breadcrumbItems">
            <template #item="{ item, props }">
                <router-link v-if="item.route" v-slot="{ href, navigate }" :to="item.route" custom>
                    <a :href="href" v-bind="props.action" @click="navigate">
                        <span :class="[item.icon, 'text-color']" />
                        <span class="text-primary font-semibold">{{ item.label }}</span>
                    </a>
                </router-link>
                <a v-else :href="item.url" :target="item.target" v-bind="props.action">
                    <span class="text-surface-700 dark:text-surface-0">{{ item.label }}</span>
                </a>
            </template>
        </Breadcrumb>

        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 p-4">
            <!-- 转换类型选择 -->
            <div class="col-span-2">
                <div class="field">
                    <label for="conversionType" class="block text-900 font-medium mb-2">转换类型</label>
                    <Dropdown id="conversionType" v-model="conversionType" :options="conversionTypes" optionLabel="name"
                        placeholder="选择转换类型" class="w-full" />
                </div>
            </div>

            <!-- 字节顺序选择 -->
            <div class="col-span-2">
                <div class="field">
                    <label class="block text-900 font-medium mb-2">字节顺序</label>
                    <div class="flex gap-4">
                        <div class="flex items-center">
                            <RadioButton v-model="byteOrder" inputId="bigEndian" name="byteOrder" value="big" />
                            <label for="bigEndian" class="ml-2">大端序</label>
                        </div>
                        <div class="flex items-center">
                            <RadioButton v-model="byteOrder" inputId="littleEndian" name="byteOrder" value="little" />
                            <label for="littleEndian" class="ml-2">小端序</label>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 输入区域 -->
            <div class="col-span-1">
                <div class="field">
                    <label for="inputValue" class="block text-900 font-medium mb-2">输入值</label>
                    <InputText id="inputValue" v-model="inputValue" placeholder="请输入数字" class="w-full"
                        @input="convertValue" />
                </div>

                <div class="field" v-if="conversionType.value === 'int' || conversionType.value === 'long'">
                    <label for="inputBase" class="block text-900 font-medium mb-2">输入进制</label>
                    <Dropdown id="inputBase" v-model="inputBase" :options="[2, 8, 10, 16]" placeholder="选择进制"
                        class="w-full" @change="convertValue" />
                </div>
            </div>

            <!-- 输出区域 -->
            <div class="col-span-1">
                <div class="field">
                    <label class="block text-900 font-medium mb-2">二进制结果</label>
                    <div
                        class="p-3 bg-surface-100 dark:bg-surface-800 rounded border-1 border-surface-300 dark:border-surface-600 min-h-3rem">
                        <pre class="m-0 text-sm">{{ binaryResult }}</pre>
                    </div>
                </div>

                <div class="field">
                    <label class="block text-900 font-medium mb-2">十六进制结果</label>
                    <div
                        class="p-3 bg-surface-100 dark:bg-surface-800 rounded border-1 border-surface-300 dark:border-surface-600 min-h-3rem">
                        <pre class="m-0 text-sm">{{ hexResult }}</pre>
                    </div>
                </div>
            </div>

            <!-- 转换说明 -->
            <div class="col-span-2">
                <div class="p-3 bg-blue-50 dark:bg-blue-900/20 rounded border-1 border-blue-200 dark:border-blue-700">
                    <h4 class="text-blue-800 dark:text-blue-300 font-medium mb-2">转换说明</h4>
                    <p class="text-blue-700 dark:text-blue-400 text-sm m-0">
                        大端模式：数据的高字节保存在内存的低地址中<br>
                        小端模式：数据的高字节保存在内存的高地址中<br>
                        默认使用大端序进行转换
                    </p>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import Dropdown from 'primevue/dropdown';
import InputText from 'primevue/inputtext';
import RadioButton from 'primevue/radiobutton';
import { ref, watch } from 'vue';
const breadcrumbHome = ref({ icon: 'pi pi-home', route: '/tooldashboard' });
const breadcrumbItems = ref([{ label: '🌟通用工具' }, { label: '字符', route: '/customtools/char' }, { label: '数字转二进制' }]);

const conversionType = ref({ name: '整数 (int)', value: 'int' });
const byteOrder = ref('big');
const inputValue = ref('');
const inputBase = ref(10);
const binaryResult = ref('');
const hexResult = ref('');

const conversionTypes = [
    { name: '浮点数 (float)', value: 'float' },
    { name: '双精度浮点数 (double)', value: 'double' },
    { name: '短整型 (short)', value: 'short' },
    { name: '整数 (int)', value: 'int' },
    { name: '长整型 (long)', value: 'long' }
];

// 监听转换类型变化
watch(conversionType, () => {
    convertValue();
});

// 监听字节顺序变化
watch(byteOrder, () => {
    convertValue();
});

const convertValue = () => {
    if (!inputValue.value) {
        binaryResult.value = '';
        hexResult.value = '';
        return;
    }

    try {
        const value = parseInputValue();

        switch (conversionType.value.value) {
            case 'float':
                convertFloat(value);
                break;
            case 'double':
                convertDouble(value);
                break;
            case 'short':
                convertShort(value);
                break;
            case 'int':
                convertInt(value);
                break;
            case 'long':
                convertLong(value);
                break;
        }
    } catch (error) {
        binaryResult.value = '转换错误: ' + error.message;
        hexResult.value = '转换错误: ' + error.message;
    }
};

const parseInputValue = () => {
    const value = inputValue.value.trim();

    if (conversionType.value.value === 'float' || conversionType.value.value === 'double') {
        return parseFloat(value);
    }

    // 对于整数类型，根据选择的进制解析
    const base = inputBase.value;
    return parseInt(value, base);
};

const convertFloat = (value) => {
    const buffer = new ArrayBuffer(4);
    const view = new DataView(buffer);
    view.setFloat32(0, value, byteOrder.value === 'little');

    const uintArray = new Uint8Array(buffer);
    binaryResult.value = Array.from(uintArray)
        .map(byte => byte.toString(2).padStart(8, '0'))
        .join(' ');

    hexResult.value = Array.from(uintArray)
        .map(byte => byte.toString(16).padStart(2, '0').toUpperCase())
        .join(' ');
};

const convertDouble = (value) => {
    const buffer = new ArrayBuffer(8);
    const view = new DataView(buffer);
    view.setFloat64(0, value, byteOrder.value === 'little');

    const uintArray = new Uint8Array(buffer);
    binaryResult.value = Array.from(uintArray)
        .map(byte => byte.toString(2).padStart(8, '0'))
        .join(' ');

    hexResult.value = Array.from(uintArray)
        .map(byte => byte.toString(16).padStart(2, '0').toUpperCase())
        .join(' ');
};

const convertShort = (value) => {
    const buffer = new ArrayBuffer(2);
    const view = new DataView(buffer);
    view.setInt16(0, value, byteOrder.value === 'little');

    const uintArray = new Uint8Array(buffer);
    binaryResult.value = Array.from(uintArray)
        .map(byte => byte.toString(2).padStart(8, '0'))
        .join(' ');

    hexResult.value = Array.from(uintArray)
        .map(byte => byte.toString(16).padStart(2, '0').toUpperCase())
        .join(' ');
};

const convertInt = (value) => {
    const buffer = new ArrayBuffer(4);
    const view = new DataView(buffer);
    view.setInt32(0, value, byteOrder.value === 'little');

    const uintArray = new Uint8Array(buffer);
    binaryResult.value = Array.from(uintArray)
        .map(byte => byte.toString(2).padStart(8, '0'))
        .join(' ');

    hexResult.value = Array.from(uintArray)
        .map(byte => byte.toString(16).padStart(2, '0').toUpperCase())
        .join(' ');
};

const convertLong = (value) => {
    const buffer = new ArrayBuffer(8);
    const view = new DataView(buffer);
    view.setBigInt64(0, BigInt(value), byteOrder.value === 'little');

    const uintArray = new Uint8Array(buffer);
    binaryResult.value = Array.from(uintArray)
        .map(byte => byte.toString(2).padStart(8, '0'))
        .join(' ');

    hexResult.value = Array.from(uintArray)
        .map(byte => byte.toString(16).padStart(2, '0').toUpperCase())
        .join(' ');
};
</script>

<style scoped>
.field {
    margin-bottom: 1.5rem;
}

pre {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-family: 'Courier New', monospace;
}

.min-h-3rem {
    min-height: 3rem;
}
</style>